package simpleTaskDispatcher.model.tasks.impl;

import java.util.HashMap;
import java.util.Map;

import simpleTaskDispatcher.model.TaskQueue;
import simpleTaskDispatcher.model.Worker;
import simpleTaskDispatcher.model.tasks.ITask;
import tradingStrategyDeveloper.api.model.utils.SequentialIDGenerator;

public abstract class AbstractTask implements ITask {

	private static Map<Class<? extends ITask>, SequentialIDGenerator > generators = new HashMap<Class<? extends ITask>, SequentialIDGenerator>();
	
	private String id;
	
	private int workValue;
	
	private TaskQueue queue;
	
	private Worker worker;
	
	private boolean executed;
	
	public AbstractTask() {
		this.id = generateID(getClass());
	}
	
	private static synchronized String generateID(Class<? extends ITask> taskClass) {
		SequentialIDGenerator seq = generators.get(taskClass);
		if (seq == null) {
			seq = new SequentialIDGenerator();
			generators.put(taskClass, seq);
		}
		
		return taskClass.getName() + "#" + seq.nextIntID();
	}
	
	@Override
	public boolean isExecuted() {
		return executed;
	}
	
	@Override
	public void markExecuted() {
		this.executed = true;
	}

	@Override
	public String getUniqueID() {
		return id;
	}
	
	@Override
	public String toString() {
		return id;
	}
	
	@Override
	public final float getWorkValue() {
		return workValue;
	}

	public TaskQueue getQueue() {
		return queue;
	}

	public AbstractTask setWorkValue(int workValue) {
		this.workValue = workValue;
		return ((AbstractTask) this);
	}
	
	@Override
	public void setTaskQueue(TaskQueue queue) {
		this.queue = queue;
	}

	public void setSharedParameter(String name, Object value) throws InterruptedException {
		queue.setSharedParameter(name, value);
	}
	
	public <T> T getContextParameter(String name) {
		return worker.get(name);
	}
	
	public void setContextParameter(String name, Object value) {
		worker.set(name, value);
	}
	
	public <T> T getSharedParameter(String name) throws InterruptedException {
		return queue.getSharedParameter(name);
	}
	
	public void multiplySharedIntegerParameter(String name, int factor)
			throws InterruptedException {
		queue.multiplySharedIntegerParameter(name, factor);
	}

	public void multiplySharedLongParameter(String name, long factor)
			throws InterruptedException {
		queue.multiplySharedLongParameter(name, factor);
	}

	public void multiplySharedFloatParameter(String name, float factor)
			throws InterruptedException {
		queue.multiplySharedFloatParameter(name, factor);
	}

	public void multiplySharedDoubleParameter(String name, double factor)
			throws InterruptedException {
		queue.multiplySharedDoubleParameter(name, factor);
	}

	public void incrementSharedIntegerParameter(String name, int increment)
			throws InterruptedException {
		queue.incrementSharedIntegerParameter(name, increment);
	}

	public void incrementSharedLongParameter(String name, long increment)
			throws InterruptedException {
		queue.incrementSharedLongParameter(name, increment);
	}

	public void incrementSharedFloatParameter(String name, float increment)
			throws InterruptedException {
		queue.incrementSharedFloatParameter(name, increment);
	}

	public void incrementSharedDoubleParameter(String name, double increment)
			throws InterruptedException {
		queue.incrementSharedDoubleParameter(name, increment);
	}

	public void setWorker(Worker worker) {
		this.worker = worker;
	}
}
